package net.qiqbframework.modelling.domain;

import net.qiqbframework.commandhandling.ApplyMore;
import net.qiqbframework.config.ConfigurationException;
import net.qiqbframework.messaging.MetaData;
import net.qiqbframework.messaging.Scope;
import net.qiqbframework.messaging.ScopeDescriptor;


public abstract class AggregateLifecycle extends Scope {

    protected static AggregateLifecycle getInstance() {
        return Scope.getCurrentScope();
    }

    protected abstract void updateFetchSource(Integer fetchSource);

    protected abstract Integer fetchSource();

    protected abstract boolean isDeleted();

    protected abstract boolean getIsLive();

    protected abstract Long version();

    protected abstract Object aggregateRoot();

    protected abstract void doMarkDeleted();


    /**
     * 添加领域事件
     *
     * @param payload
     * @param metaData
     * @param <T>
     * @return
     */
    protected abstract <T> ApplyMore addEvent(T payload, MetaData metaData);


    public void execute(Runnable task) {
        try {
            executeWithResult(() -> {
                task.run();
                return null;
            });
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new ConfigurationException("Exception while invoking a task for an aggregate", e);
        }
    }

    @Override
    public ScopeDescriptor describeScope() {
        return new AggregateScopeDescriptor(type(), this::identifier);
    }

    protected abstract String type();

    /**
     * 获取聚合唯一标识符。
     *
     * @return 如果是聚合对象则返回的是聚合根id，聚合服务将返回服务名称
     */
    protected abstract Object identifier();
}
